Verilog 是一個硬體描述語言,除了設計硬體之外,他也涵蓋了 C 語言等軟體設計特色。
因此 Verilog 的設計思維其實非常廣泛的,同一個電路,程式碼的表示方式也不唯一!
這裡指的程式碼不唯一,是因為我們可以用偏向數位邏輯設計的角度去時做這個電路,也可以使用軟體思維來設計。
我們可以從一個簡單的例題來說明不同的設計思維。
下圖是一個 4 對 1 的多工器(MUX),根據不同的選擇線(S0, S1),輸出(z)會得到不同的結果。
舉例來說,當(S1, S0) = (1, 0) 時,z = C。(圖片來源:維基百科)
這個方式會比較偏向軟體中的設計。這個題目如果是放在 C 語言的練習平台上,相信我們會直接用 switch / case
或 if / else
來解答。這種設計思維就是如此,我們只需要搭配一組 case
就可以模擬多工器了!
always @ (*) begin
case ({S1, S0})
2'b00: out = A;
2'b01: out = B;
2'b10: out = C;
2'b11: out = D;
endcase
end
這種方式會開始使用到邏輯設計所學的概念,但是又有一點 C 語言的背影在。如果學過 C 語言,其中的位元運算跟這個設計思維我認為很相似。
那怎麼運用在這個題目呢?
首先,我們需要先把布林關係式求出來。方法很簡單,就是畫出真值表,行有餘力,可以透過卡諾圖化簡關係式。
這個關係式最終就會是以變數和位元且(bitwise-and, &
)、位元或(bitwise-or, |
)、位元反向(bitwise-not, ~
)來表示,那不就是 C 語言的位元運算嗎?
根據真值表可以得到 z = (A S0' S1') + (B S0 S1') + (C S0' S1) + (D S0 S1)
在布林運算式中,加法代表「或」運算,乘法代表「且」運算,
'
代表「反」運算
assign z = (A & ~S0 & ~S1) | (B & S0 & ~S1) | (C & ~S0 & S1) | (D & S0 & S1);
這個方式可以說是把 Dataflow Modeling 中的位元運算都改成用邏輯閘表示。
同樣的布林運算式 z = (A S0' S1') + (B S0 S1') + (C S0' S1) + (D S0 S1)
,我們可以用 Verilog 中的內建邏輯閘來呈現!
但是其內建邏輯閘模型中,只提供兩個輸入和一個輸出,因此如果要表達上面的布林式會顯得相對冗長(超過 10 個邏輯閘)。建議先用卡諾圖先行化簡再接著實作 Verilog。
透過一個基本的數位電路元件「多工器」,相信大家都可以理解這三種設計思維的差異!
我相信,先了解這幾種設計思維,在未來我們更能掌握 Verilog 。